<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">











<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>standalone-archetype - Guía del desarrollador de standalone-archetype - 1.0.27-SNAPSHOT</title>
    <style type="text/css" media="all">
      @import url("./css/maven-base.css");
      @import url("./css/maven-theme.css");
      @import url("./css/site.css");
    </style>
    <link rel="stylesheet" href="./css/print.css" type="text/css" media="print" />
          <meta name="author" content="carlosg@tid.es" />
          </head>
  <body class="composite">
    <div id="banner">
                  <a href="http://www.softwaresano.com" id="bannerLeft">
    
                                            <img src="img/logo.png" alt="" />
    
            </a>
                    <div class="clear">
        <hr/>
      </div>
    </div>
    <div id="breadcrumbs">
          
  

  
    
  
  
    
            <div class="xleft">
        Publicado el: 2011-01-11
                      </div>
            <div class="xright">            <a href="developerGuide.html">Normas de desarrollo</a>
            |
                <a href="index.html">Arquetipo básico</a>
            |
                <a href="maven-repositories.html">Repositorios de maven</a>
            
  

  
    
  
  
    
  </div>
      <div class="clear">
        <hr/>
      </div>
    </div>
    <div id="leftColumn">
      <div id="navcolumn">
           
  

  
    
  
  
    
                   <h5>Descargas</h5>
            <ul>
              
    <li class="none">
                    <a href="downloads/releases.html">Releases</a>
          </li>
              
    <li class="none">
                    <a href="downloads/snapshots.html">Snapshot</a>
          </li>
              
    <li class="none">
                    <a href="changes-report.html">Release Notes</a>
          </li>
              
    <li class="none">
                    <a href="license.html">Licencia</a>
          </li>
          </ul>
              <h5>Standalone Archetype</h5>
            <ul>
              
    <li class="none">
                    <a href="index.html">Introducción</a>
          </li>
              
    <li class="none">
                    <a href="installation.html">Instalación</a>
          </li>
              
    <li class="none">
                    <a href="user_guide.html">Guía de usuario</a>
          </li>
          </ul>
              <h5>Desarrollo</h5>
            <ul>
              
    <li class="none">
                    <a href="source-repository.html">Fuentes</a>
          </li>
              
    <li class="none">
                    <a href="integration.html">Integración continua</a>
          </li>
              
    <li class="none">
              <strong>Normas de desarrollo</strong>
        </li>
          </ul>
              <h5>Documentación del proyecto</h5>
            <ul>
              
                
              
      
            
      
            
      
            
      
            
      
            
      
            
      
            
      
            
      
            
      
            
      
              
        <li class="collapsed">
                    <a href="project-info.html">Información del proyecto</a>
                </li>
              
                
              
      
            
      
              
        <li class="collapsed">
                    <a href="project-reports.html">Informes del proyecto</a>
                </li>
          </ul>
                                                           
                        
                        
            <a href="http://pimpam.googlecode.com/" title="pimpam" class="poweredBy">
                            <img alt="pimpam" src="http://pimpam.googlecode.com/files/builtByPimpam.png" />
            </a>
                               
  

  
    
  
  
    
        </div>
    </div>
    <div id="bodyColumn">
      <div id="contentBox">
        <div class="section"><h2>Guía del desarrollador <b>standalone-archetype</b></h2>
<p>El desarrollo de un proyecto con el arquetipo <b>standalone-archetype</b> ha de cumplir los siguientes requisitos:</p>
<ul><li><a href="#Estándares_de_codificación">Estándares de codificación</a></li>
<li><a href="#Generación_de_clases">Generación de clases</a></li>
<li><a href="#Desarrollo_basado_en_interfaces">Desarrollo basado en interfaces</a></li>
<li>Implementación de las pruebas unitarias para comprobar el funcionamiento de los interfaces anteriores, aplicando la técnica del Test Development Driven.</li>
<li>En el caso que no se vaya a tener una implementación rápida del interfaz. Generar objetos Mock</li>
<li>Implementación de los interfaces</li>
<li>Independizar la instalación de los diferentes entornos (desarrollo, integración, producción)</li>
<li><a href="#Concatenación_de_cadenas">Concatenación de cadenas</a></li>
<li><a href="#Utilización_de_codeguards">Utilización de codeguards</a></li>
<li><a href="#Utilización_de_asserts">Utilización de asserts para validación de los parámetros de entrada</a></li>
<li><a href="#Utilización_de_finals">Utilización de final para hacer un código más eficiente y más comprensible</a></li>
<li><a href="#Trazas">Trazas</a></li>
<li><a href="#Tratamiento_de_excepciones">Tratamiento de excepciones</a></li>
<li><a href="#Entregas_en_el_SVN">Entregas en el SVN</a></li>
</ul>
<div class="section"><h3><a name="Estándares_de_codificación">Estándares de codificación</a></h3>
<ul><li><b>Encoding UTF-8</b>. En Eclipse: (Window --&gt; Preferences --&gt; General --&gt; Workspace --&gt; UTF-8)</li>
<li><b><a class="externalLink" href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html">Java Conventions</a></b>. En Eclipse (Window --&gt; Preferences --&gt; Java --&gt; Code Style --&gt; Formatter --&gt; Import --&gt; <a href="customEditors/Eclipse/CustomJavaConventions.xml"> CustomJavaConventions.xml</a>). </li>
<li><b>Substitución de tabuladores por espacios en ficheros Java</b>. En Eclipse ( Window --&gt; Preferences --&gt; General --&gt; Editors --&gt; Text Editors --&gt; Insert spaces for tabs (Displayed tab width 4).</li>
<li><b>Substitución de tabuladores por espacios en ficheros XML</b>. En Eclipse ( Window --&gt; Preferences --&gt; XML --&gt; XML Files --&gt; Editors --&gt; Indent Using Spaces --&gt; Tab Size 4). </li>
<li>Automatización del formateo de código, inclusión de finals, etc. En Eclipse (Window --&gt; Preferences --&gt; Java --&gt; Code Style --&gt; Clean Up --&gt; Import <a href="customEditors/Eclipse/CustomCleanUpConventions.xml"> CustomCleanUpConventions.xml</a>). Cuando una clase ya esté correctamente implementada formatearla añadiendo finals, eliminando campos innecesarios, etc. En Eclipse (Source --&gt; Clean Up).</li>
</ul>
</div>
<div class="section"><h3><a name="Generación_de_clases">Generación de clases</a></h3>
<p><b>Nombres de paquetes, clases, métodos y propiedades</b> </p>
<ul><li>Todos los nombres de paquetes, clases, métodos y propiedades deben ser lo más explicativos posible, aunque el resultado sea largo. Utilizar sólo una letra o las 4 primeras puede generar a confusión. Además irán todos en inglés.</li>
<li>Los nombres de los paquetes normalmente irán en plural: <div class="source"><pre>es.tid.ad.tools.services</pre>
</div>
</li>
<li>Sin embargo, los nombres de las clases irán en singular:<div class="source"><pre>es.tid.ad.tools.services.SectionService</pre>
</div>
</li>
<li>Las interfaces llevarán el nombre sin ningún sufijo: <div class="source"><pre>es.tid.ad.tools.services.SectionService</pre>
</div>
</li>
<li>Mientras que cada implementación llevará uno que la identifique: <div class="source"><pre>es.tid.ad.tools.services.impl.SectionServiceImpl</pre>
</div>
</li>
<li>Si tuviéramos más de una implementación se crearía un paquete para cada una y un sufijo para cada una: <div class="source"><pre>es.tid.ad.tools.data.access.daos.SectionDao
es.tid.ad.tools.data.access.daos.hibernate.SectionDaoHibernate
es.tid.ad.tools.data.access.daos.jdbc.SectionDaoJdbc</pre>
</div>
</li>
</ul>
<p><b>toString</b> Al menos hay que implementar los métodos toString de las clases que son estructuras de datos (módulos &quot;data&quot;) El formato debe ser: [name=value,name=value,...] Se debe implementar usando StringBuilder por cuestiones de eficiencia; hay que tener en cuenta que hay que hacer un new del stringbuilder ya que no está sincronizado. Para configurarlo de forma automática, instalarse el plugin jutils de eclipse (descomprimir el contenido del zip dentro de la carpeta plugins de eclipse): </p>
<div class="source"><pre> http://sourceforge.net/project/showfiles.php?group_id=157234&amp;package_id=175708&amp;release_id=521450</pre>
</div>
<p>Después, configurar el plugin para que utilice como base StringBuilder (Window --&gt; Preferences --&gt; JUtils --&gt; toString, seleccionar StringBuilder Mode y cambiar la plantilla de código por:</p>
<div class="source"><pre>public String toString() {
   StringBuilder sb = new StringBuilder(&quot;[[${class_name}]&quot;);
   sb.append(&quot;[${attribute} = &quot;).append(this.${attribute}).append(&quot;]&quot;);
   sb.append(&quot;]&quot;);
   return sb.toString();
}</pre>
</div>
<p>Para utilizarlo, cuando se genere una clase “tipo POJO” (dentro del proyecto acl-data, normalmente), pulsar con el botón derecho del ratón sobre la clase, seleccionar JUtils --&gt; toString, y el código se generará con el formato adecuado. Si el método ya estaba creado, lo sustituirá (por ejemplo, si se ha añadido una nueva propiedad a la clase). </p>
</div>
<div class="section"><h3><a name="Desarrollo_basado_en_interfaces">Desarrollo basado en interfaces</a></h3>
<p><a href="user_guide.html#Ampliar_el_interfaz_Component">Ver ejemplo</a></p>
</div>
<div class="section"><h3><a name="Implementación_de_las_pruebas">Implementación de las pruebas</a></h3>
<p><a href="user_guide.html#Implementar_los_tests_necesarios_para_probar_el_método_SQRT">Ver ejemplo</a></p>
</div>
<div class="section"><h3><a name="Implementaciones_virtuales">Implementaciones virtuales</a></h3>
<p><a href="user_guide.html#Modificar_la_clase_virtualMock_que_implementa_la_interfaz_Component">Ver ejemplo</a></p>
</div>
<div class="section"><h3><a name="Implementación_de_las_interfaces">Implementación de las interfaces</a></h3>
<p><a href="user_guide.html#Implementar_el_nuevo_método_SQRT">Ver ejemplo</a></p>
</div>
<div class="section"><h3><a name="Configuración_independiente_del_entorno">Configuración independiente del entorno</a></h3>
<p>Cada entorno (desarrollo, integración y producción) deberían tener configuraciones separadas. </p>
</div>
<div class="section"><h3><a name="Concatenación_de_cadenas">Concatenación de cadenas</a></h3>
<p>Evitar la concatenación de cadenas. Por ejemplo:</p>
<div class="source"><pre>#MAL
String message = &quot;Calculando la suma de [&quot;+a+&quot;] y [&quot;+b+&quot;]&quot;;</pre>
</div>
<p>Sustituirlo por:</p>
<div class="source"><pre>final String message = new StringBuilder(&quot;Calculando la suma de [&quot;).append(a).
                                       append(&quot;y [&quot;).append(b).append(&quot;]&quot;);</pre>
</div>
<p>o mejor por:</p>
<div class="source"><pre> final String message = MessageFomart.format(&quot;Calculando la suma de [{0}] y [{1}]&quot;,
                                      new Object[]{a},{b});</pre>
</div>
</div>
<div class="section"><h3><a name="Utilización_de_codeguards">Utilización de codeguards</a></h3>
<p>Evitar ejecutar código que no se utilizará. Por ejemplo si el nivel de trazas es INFO, en el código siguiente se ejecutará <b>format(&quot;Calculando la suma de [<a name="a0">0</a>] y [<a name="a1">1</a>]&quot;,new Object[]<a name="a_b">a, b</a>))</b> y después no será utilizado por el sistema de trazas ya que las trazas a nivel de DEBUG están deshabilitadas.</p>
<div class="source"><pre>  LOG.debug(format(&quot;Calculando la suma de [{0}] y [{1}]&quot;,
                             new Object[]{a, b}));</pre>
</div>
<p>Sustituir el código por:</p>
<div class="source"><pre>  if (LOG.isDebugEnabled()) {
            LOG.debug(format(&quot;Calculando la suma de [{0}] y [{1}]&quot;,
                             new Object[]{a, b}));
        }</pre>
</div>
</div>
<div class="section"><h3><a name="Utilización_de_asserts">Utilización de asserts</a></h3>
<p>Para validar los parámetros de entrada a un método se han de utilizar asserts, de forma que si no se cumple la restricción que se ha indicado en el assert se aborte la ejecución del método. En general, sólo deberían ser usados en casos en que la situación comprobada sea algo que NUNCA debería pasar</p>
<div class="source"><pre> public Double sqrt(final Double a){
    assert (a != null) : &quot;sqrt: parameter a is null&quot;;
    ...
 }</pre>
</div>
</div>
<div class="section"><h3><a name="Utilización_de_finals">Utilización de finals</a></h3>
<p>Cuando un parámetro o una variable de un método no deba ser modificada se ha de añadir el modificador <b>final</b>. Los parámetros de los métodos implementados han de ser obligatoriamente <b>final</b>, ya que un parámetro de un método debe mantener el valor cuando acabe la ejecución de dicho método. Ejemplo:</p>
<div class="source"><pre> public Double sqrt(final Double a){
    assert (a != null) : &quot;sqrt: parameter a is null&quot;;
    final String message = &quot;Calculando la raíz cuadrada&quot;;
    ...
    Double result = null;
    result = Math.sqrt(a);
    return result;
 }</pre>
</div>
</div>
<div class="section"><h3><a name="Trazas">Trazas</a></h3>
<div class="section"><h4><a name="Niveles_de_trazas">Niveles de trazas</a></h4>
<table class="bodyTable"><tbody><tr class="a"><td align="left"><b>Nivel</b></td>
<td align="left"><b>Activación en Producción</b></td>
<td align="left"><b>Descripción</b></td>
<td align="left"><b>Ejemplo</b></td>
</tr>
<tr class="b"><td align="left">DEBUG</td>
<td align="left">NO</td>
<td align="left">mensajes de depuración que permitan identificar problemas.</td>
<td align="left">Valor devuelto por un método</td>
</tr>
<tr class="a"><td align="left">INFO</td>
<td align="left">SI</td>
<td align="left">mensajes en puntos clave que permitan seguir el flujo de ejecución (Seguir un caso de uso).</td>
<td align="left">Valor de los parámetros de entrada de un método</td>
</tr>
<tr class="b"><td align="left">WARN</td>
<td align="left">SI</td>
<td align="left">mensajes que notifiquen errores que no degraden el funcionamiento de la aplicación.</td>
<td align="left">Cuando los parámetros de entrada no están dentro del rango esperado (Por ejemplo: se espera un valor numérico y nos llega un String)</td>
</tr>
<tr class="a"><td align="left">ERROR</td>
<td align="left">SI</td>
<td align="left">mensajes que permitan la detección de errores</td>
<td align="left">Se ha producido una excepción que no se debe dejar pasar y no está controlada. Ej: Se ha perdido la conexión a la Base de Datos.</td>
</tr>
<tr class="b"><td align="left">FATAL</td>
<td align="left">SI</td>
<td align="left">mensajes críticos del sistema.</td>
<td align="left">Cualquier petición al sistema falla tras este error.</td>
</tr>
</tbody>
</table>
<p>Cuando en un método es necesario escribir más de una traza de INFO, probablemente es que ese método está haciendo demasiado trabajo. En resumen, en un método se escribirá como mínimo una traza de INFO con los parámetros de entrada y una traza de DEBUG con el valor devuelto.</p>
</div>
<div class="section"><h4><a name="Creación_de_Loggers">Creación de Loggers</a></h4>
<p>Cada clase debe tener su propio Logger, que siempre debe estar declarado con los modificadores de acceso <b>private static final</b></p>
<div class="source"><pre>public final class Component implements com.foo.calculator.Component {
    private static final Log LOG = LogFactory.getLog(Component.class);
...
}</pre>
</div>
</div>
<div class="section"><h4><a name="Formateo_mensaje_de_trazas">Formateo mensaje de trazas</a></h4>
<p>Los parámetros que se incluyan en las trazas han de ir entre corchetes. Ejemplo:</p>
<div class="source"><pre>if (LOG.isDebugEnabled()) {
        LOG.debug(format(&quot;Calculando la suma de [{0}] y [{1}]&quot;,
                             new Object[]{a, b}));
}</pre>
</div>
</div>
</div>
<div class="section"><h3><a name="Tratamiento_de_excepciones">Tratamiento de excepciones</a></h3>
<div class="section"><h4>No ocultar las excepciones</h4>
<p>Una excepción debe ser propagada hacia los niveles superiores para ser tratada o al menos registrada en los logs para ser analizada. Un bloque try-catch vacío oculta un problema, complica su localización y por tanto su resolución.</p>
</div>
<div class="section"><h4>Favorecer el uso de excepciones estándar</h4>
<p>El uso de excepciones estándar aumenta la legibilidad y reusabilidad del código. Si una condicion excepcional puede ser expresada con una excepcion ya existente en el lenguaje Java, no debemos reinventarla. Algunas de las mas comunes que debemos emplear son:</p>
<ul><li><b>IllegalArgumentException</b>: cuando un parámetro es inadecuado.</li>
<li><b>IllegalStateException</b>: cuando el estado de un objeto no permite una operación sobre el.</li>
<li><b>NullPointerException</b>: cuando un parámetro es nulo.</li>
<li><b>IndexOutOfBoundsException</b>: cuando un parámetro usado como índice está fuera de rango.</li>
<li><b>UnsupportedOperationException</b>: cuando el objeto no soporta la invocación de un metodo.</li>
</ul>
</div>
<div class="section"><h4>Tratamiento de la excepción en el ámbito mas reducido posible</h4>
<p>Facilita su localización y recuperación.</p>
</div>
<div class="section"><h4>catch precisos</h4>
<p>Cuando se pone un catch, procurad que sea lo mas preciso posible, ya que ayuda a determinar la causa del problema. Ejemplo:</p>
<div class="source"><pre>    catch FileNotFoundException     es mejor que
    catch IOException</pre>
</div>
</div>
<div class="section"><h4>Uso de RuntimeException</h4>
<p>Las excepciones del tipo RuntimeException no es obligatorio capturarlas, y pueden subir hacia las clases superiores y tirar todo el sistema. Deben utilizarse con sumo cuidado, y sólo lanzarse ante errores no recuperables</p>
</div>
<div class="section"><h4>Uso de finally</h4>
<p>Utilizar la cláusula finally siempre que haya algún recurso crítico(por ejemplo apertura de sockets) que deba ser liberado independientemente del flujo que siga la ejecución.</p>
</div>
<div class="section"><h4>Traceo de excepciones</h4>
<p>Cuando se produce una excepción, se ha de tracear, con nivel del Error. Ej:</p>
<div class="source"><pre> final String message = MessageFormat.format(&quot;The class [{0}] cannot be found in [{1}]&quot;, className, searchPath);
 if (logger.isErrorEnabled()) {
    logger.error(message);
 }
 throw new ClassNotFoundException(message, ex);</pre>
</div>
</div>
</div>
<div class="section"><h3><a name="Entregas_en_el_SVN">Entregas en el SVN</a></h3>
<p>En un entorno de integración continua es muy importante que todo lo que se suba al repositorio funcione. Para ello a la hora de hacer una entrega al repositorio hay que seguir los siguientes pasos:</p>
<ul><li>Comprobar si la última ejecución en la máquina de integración contínua fue correcta, sino lo fue avisad al responsable/s de la última entrega que es la que le ha hecho fallar</li>
<li>Bajarse todas las actualizaciones que haya en el repositorio</li>
<li>Volver a generar, <a href="../installation.html">instalar en local</a> y probad que funciona la aplicación</li>
<li>Asegurarse que todos los fuentes que entregamos están con formato UTF-8 (En eclipse: Preferences --&gt; General --&gt; Workspace --&gt; UTF-8)</li>
<li>En el caso de ficheros java hay que formatearlo siguiendo el estilo de las <a class="externalLink" href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html">Java Conventions</a>. Si se utiliza eclipse (Preferences --&gt; Java --&gt; Code Style --&gt; Java Conventions)</li>
<li>En el caso de que se trate de una nueva funcionalidad, corrección de un error o alguna otra modificación importante, se ha de incluir en el fichero src/changes/changes.xml siguiendo la guía definida <a class="externalLink" href="http://maven.apache.org/plugins/maven-changes-plugin/changes.html">aquí</a>.</li>
<li>Ignorar todos los ficheros que no se hayan de subir al repositorio. Se deberían añadir al svn-ignore los siguientes ficheros/directorios: .settings (eclipse), .prefs (eclipse), .classpath (eclipse), .Thumbs (para los de Windows), .project (eclipse), .springBeans (si se usa Spring IDE), target, log., directorio META-INF generado automáticamente, MANIFEST.MF que se hayan generado automáticamente</li>
<li>Agrupar los commits por funcionalidades(entregas atómicas), y etiquetarlos como se indica en la siguiente tabla:<table class="bodyTable"><tbody><tr class="a"><td align="left"><b>Etiqueta</b></td>
<td align="left"><b>Descripción</b></td>
</tr>
<tr class="b"><td align="left">FIXED XXXXX</td>
<td align="left">(donde XXXX es el identificador del error que se ha asignado en el sistema de Bugtracking): Se soluciona un error</td>
</tr>
<tr class="a"><td align="left">FEATURE</td>
<td align="left">Se ha añadido alguna funcionalidad nueva</td>
</tr>
<tr class="b"><td align="left">MINOR</td>
<td align="left">Cambios menores que no son ni improvements ni features (que no hace falta indicar en las Release Notes)</td>
</tr>
<tr class="a"><td align="left">IMPROVEMENT</td>
<td align="left">Se ha mejorado alguna rutina o GUI (cualquier mejora tipo rendimiento, usabilidad,...)</td>
</tr>
<tr class="b"><td align="left">REFACTOR</td>
<td align="left">Se hace algún move talibán en el SVN o para refactors</td>
</tr>
<tr class="a"><td align="left">DOCUMENTATION</td>
<td align="left">Cualquier cambio relacionado con la documentación</td>
</tr>
<tr class="b"><td align="left">MERGE</td>
<td align="left">Fusionar 2 ramas del repositorio</td>
</tr>
<tr class="a"><td align="left">SVN</td>
<td align="left">Mantenimiento del repositorio (Crear branches/tags, borrarlos, renombrar carpetas,...)</td>
</tr>
</tbody>
</table>
</li>
</ul>
</div>
</div>

      </div>
    </div>
    <div class="clear">
      <hr/>
    </div>
    <div id="footer">
      <div class="xright">&#169;  
          2011
    
          Softwaresano.com
          
  

  
    
  
  
    
  </div>
      <div class="clear">
        <hr/>
      </div>
    </div>
  </body>
</html>
